home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA-CD 2
/
Amiga-CD - Volume 2.iso
/
ungepackte_daten
/
1995
/
6
/
02
/
patch-work
/
patchopen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-01
|
3KB
|
158 lines
/*
** PatchOpen von Patrick Ohly
** Beispiel-Patch der Open-Funktion
** © 1994 Patrick Ohly
*/
#ifdef _DCC
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#else
#include <proto/exec.h>
#include <proto/dos.h>
#endif
#include <clib/alib_protos.h>
#include <stdio.h>
#include <string.h>
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/semaphores.h>
#include <dos/dos.h>
#include "PatchUtil.h"
#define PATCH_PORT "PatchDosOpen Port"
/* in amiga.lib enthalten */
extern __far LONG LVOOpen;
/* CTRL-C-Handling unterdrücken */
#ifdef _DCC
void chkabort(void) { }
#endif
/*
** Ausgabe über dieses FileHandle
** muß durch Semaphore geschuetzt werden.
*/
struct SignalSemaphore FH_Sema;
BPTR FH;
/*
** die vorherige Funktion
** !!! Achtung !!!
** Register A6 muß weiterhin einen Zeiger auf die
** jeweilige Library enthalten!
** Da der Compiler dies bei Zeigern auf die
** Funktionen nicht automatisch macht, muß ein
** weiteres Argument hinzugefügt werden!
*/
__regargs BPTR (* OldOpen)(__D1 char *name,
__D2 LONG mode,
__A6 struct DosLibrary *DOSBase);
/* Anzahl der gerade aktiven Funktions-Aufrufe */
WORD FunctionCounter = 0;
/*
** gibt bei jedem Aufruf von Open() Filename und
** Modus aus - verwendet dazu Standardausgabe
*/
__regargs __geta4 __interrupt BPTR NewOpen(
__D1 char *name, __D2 LONG mode)
{
char buffer[120];
BPTR fh;
FunctionCounter++;
sprintf(buffer, "\nFileName: %.68s\n"
"Zugriff: ", name);
switch(mode)
{
case MODE_OLDFILE:
strcat(buffer, "MODE_OLDFILE\n");
break;
case MODE_NEWFILE:
strcat(buffer, "MODE_NEWFILE\n");
break;
case MODE_READWRITE:
strcat(buffer, "MODE_READWRITE\n");
break;
default:
strcat(buffer, "unbekannt\n");
break;
}
/* vor Ausgabe Semaphore anfordern */
ObtainSemaphore(&FH_Sema);
Write(FH, buffer, strlen(buffer));
ReleaseSemaphore(&FH_Sema);
/* Original-Funktion aufrufen und deren
Resultat zurückgeben */
fh = OldOpen(name, mode, DOSBase);
FunctionCounter--;
return(fh);
}
int main(int argc, char **argv)
{
struct MsgPort *msg_port;
if(msg_port = FindPort(PATCH_PORT))
{
/* bereits installiertes PatchDosOpen
entfernen */
Signal(msg_port->mp_SigTask,
1L<<msg_port->mp_SigBit);
puts("Versuche bereits installiertes"
" PatchOpen zu entfernen...");
}
else
{
/* neu installieren
erzeuge öffentlichen Port */
if(msg_port = CreatePort(PATCH_PORT, 0))
{
APTR handle;
InitSemaphore(&FH_Sema);
FH = Output();
Forbid();
OldOpen = SafeSetFunction((struct Library *)DOSBase,
(LONG)&LVOOpen, NewOpen,
&handle);
Permit();
if(OldOpen)
{
puts("PatchOpen wurde installiert.");
/* warte auf Ctrl-C oder nochmaligen
Start von PatchDosOpen */
Wait(SIGBREAKF_CTRL_C |
1L<<msg_port->mp_SigBit);
SetSignal(0, SIGBREAKF_CTRL_C);
RemoveFunction(OldOpen, handle);
DeletePort(msg_port);
/* unsere Funktion steht nicht mehr im
Vektor, aber andere Tasks könnten immer
noch unseren Code benutzen
=> noch warten */
do Delay(10);
while(FunctionCounter);
puts("PatchOpen wurde entfernt.");
}
else
puts("Konnte Open() nicht patchen!");
}
}
return(0);
}